﻿using System;
using GeoAPI.Geometries;
using NetTopologySuite.Algorithm;

namespace NetTopologySuite.Geometries
{
	public class Triangle
	{
		public Coordinate P0
		{
			get
			{
				return this._p0;
			}
			set
			{
				this._p0 = value;
			}
		}

		public Coordinate P1
		{
			get
			{
				return this._p1;
			}
			set
			{
				this._p1 = value;
			}
		}

		public Coordinate P2
		{
			get
			{
				return this._p2;
			}
			set
			{
				this._p2 = value;
			}
		}

		public static bool IsAcute(Coordinate a, Coordinate b, Coordinate c)
		{
			return AngleUtility.IsAcute(a, b, c) && AngleUtility.IsAcute(b, c, a) && AngleUtility.IsAcute(c, a, b);
		}

		public static HCoordinate PerpendicularBisector(Coordinate a, Coordinate b)
		{
			double num = b.X - a.X;
			double num2 = b.Y - a.Y;
			HCoordinate p = new HCoordinate(a.X + num / 2.0, a.Y + num2 / 2.0, 1.0);
			HCoordinate p2 = new HCoordinate(a.X - num2 + num / 2.0, a.Y + num + num2 / 2.0, 1.0);
			return new HCoordinate(p, p2);
		}

		public static Coordinate Circumcentre(Coordinate a, Coordinate b, Coordinate c)
		{
			double x = c.X;
			double y = c.Y;
			double num = a.X - x;
			double num2 = a.Y - y;
			double num3 = b.X - x;
			double num4 = b.Y - y;
			double num5 = 2.0 * Triangle.Det(num, num2, num3, num4);
			double num6 = Triangle.Det(num2, num * num + num2 * num2, num4, num3 * num3 + num4 * num4);
			double num7 = Triangle.Det(num, num * num + num2 * num2, num3, num3 * num3 + num4 * num4);
			double x2 = x - num6 / num5;
			double y2 = y + num7 / num5;
			return new Coordinate(x2, y2);
		}

		private static double Det(double m00, double m01, double m10, double m11)
		{
			return m00 * m11 - m01 * m10;
		}

		public static Coordinate InCentre(Coordinate a, Coordinate b, Coordinate c)
		{
			double num = b.Distance(c);
			double num2 = a.Distance(c);
			double num3 = a.Distance(b);
			double num4 = num + num2 + num3;
			double x = (num * a.X + num2 * b.X + num3 * c.X) / num4;
			double y = (num * a.Y + num2 * b.Y + num3 * c.Y) / num4;
			return new Coordinate(x, y);
		}

		public static Coordinate Centroid(Coordinate a, Coordinate b, Coordinate c)
		{
			double x = (a.X + b.X + c.X) / 3.0;
			double y = (a.Y + b.Y + c.Y) / 3.0;
			return new Coordinate(x, y);
		}

		public static double LongestSideLength(Coordinate a, Coordinate b, Coordinate c)
		{
			double num = a.Distance(b);
			double num2 = b.Distance(c);
			double num3 = c.Distance(a);
			double num4 = num;
			if (num2 > num4)
			{
				num4 = num2;
			}
			if (num3 > num4)
			{
				num4 = num3;
			}
			return num4;
		}

		public static Coordinate AngleBisector(Coordinate a, Coordinate b, Coordinate c)
		{
			double num = b.Distance(a);
			double num2 = b.Distance(c);
			double num3 = num / (num + num2);
			double num4 = c.X - a.X;
			double num5 = c.Y - a.Y;
			return new Coordinate(a.X + num3 * num4, a.Y + num3 * num5);
		}

		public static double Area(Coordinate a, Coordinate b, Coordinate c)
		{
			return System.Math.Abs(a.X * (c.Y - b.Y) + b.X * (a.Y - c.Y) + c.X * (b.Y - a.Y)) / 2.0;
		}

		public static double SignedArea(Coordinate a, Coordinate b, Coordinate c)
		{
			return ((c.X - a.X) * (b.Y - a.Y) - (b.X - a.X) * (c.Y - a.Y)) / 2.0;
		}

		public static double Area3D(Coordinate a, Coordinate b, Coordinate c)
		{
			double num = b.X - a.X;
			double num2 = b.Y - a.Y;
			double num3 = b.Z - a.Z;
			double num4 = c.X - a.X;
			double num5 = c.Y - a.Y;
			double num6 = c.Z - a.Z;
			double num7 = num2 * num6 - num3 * num5;
			double num8 = num3 * num4 - num * num6;
			double num9 = num * num5 - num2 * num4;
			return System.Math.Sqrt(num7 * num7 + num8 * num8 + num9 * num9) / 2.0;
		}

		public static double InterpolateZ(Coordinate p, Coordinate v0, Coordinate v1, Coordinate v2)
		{
			double x = v0.X;
			double y = v0.Y;
			double num = v1.X - x;
			double num2 = v2.X - x;
			double num3 = v1.Y - y;
			double num4 = v2.Y - y;
			double num5 = num * num4 - num2 * num3;
			double num6 = p.X - x;
			double num7 = p.Y - y;
			double num8 = (num4 * num6 - num2 * num7) / num5;
			double num9 = (-num3 * num6 + num * num7) / num5;
			return v0.Z + num8 * (v1.Z - v0.Z) + num9 * (v2.Z - v0.Z);
		}

		public Triangle(Coordinate p0, Coordinate p1, Coordinate p2)
		{
			this._p0 = p0;
			this._p1 = p1;
			this._p2 = p2;
		}

		public Coordinate InCentre()
		{
			return Triangle.InCentre(this.P0, this.P1, this.P2);
		}

		public bool IsAcute()
		{
			return Triangle.IsAcute(this._p0, this._p1, this._p2);
		}

		public Coordinate Circumcentre()
		{
			return Triangle.Circumcentre(this._p0, this._p1, this._p2);
		}

		public Coordinate Centroid()
		{
			return Triangle.Centroid(this._p0, this._p1, this._p2);
		}

		public double LongestSideLength()
		{
			return Triangle.LongestSideLength(this._p0, this._p1, this._p2);
		}

		public double Area()
		{
			return Triangle.Area(this._p0, this._p1, this._p2);
		}

		public double SignedArea()
		{
			return Triangle.SignedArea(this._p0, this._p1, this._p2);
		}

		public double Area3D()
		{
			return Triangle.Area3D(this._p0, this._p1, this._p2);
		}

		public double InterpolateZ(Coordinate p)
		{
			if (p == null)
			{
				throw new System.ArgumentNullException("p", "Supplied point is null.");
			}
			return Triangle.InterpolateZ(p, this._p0, this._p1, this._p2);
		}

		private Coordinate _p0;

		private Coordinate _p1;

		private Coordinate _p2;
	}
}
